package fem3d;

import java.util.ArrayList;

import math2.PulseFunctionRToR;
import fem2.AbstractStructuralDynamicsDemo;
import fem2.Constraint;
import fem2.Element;
import fem2.Force;
import fem2.MaterialModel;
import fem2.Mesh;
import fem2.MeshGenerator;
import fem2.MeshPart;
import fem2.MeshUtilities;
import fem2.Model;
import fem2.Node;
import fem2.analysis.Analysis;
import fem2.analysis.FreeVibrationAnalysis;
import fem2.element.StructuralElement;
import fem2.enu.EchoLevelType;
import fem2.enu.MassMatrixType;
import fem2.enu.NewmarkType;
import fem2.enu.State;
import fem2.material.StVenantKirchhoffMM;
import fem2.pre_and_post.GidMeshGenerator;
import fem2.strategies.Strategy;

/**
 * @author hbui
 * 
 */
public class Beam3dFreeVibration extends AbstractStructuralDynamicsDemo {

	public Beam3dFreeVibration() {
		projectDir = "/home/hbui/kratos_janosch";
		projectName = "beam3d.gid";
		// meshFileName = "mesh2-dynamics.msh"; // tetrahedra mesh
		// meshFileName = "mesh1-dynamics-Newmark.msh"; // structured hexahedra
		// // mesh
		meshFileName = "mesh1-dynamics-NewmarkCrisfield.msh"; // structured
																// hexahedra
																// mesh
	}

	@Override
	public Analysis createAnalysis(Model m) {
		Analysis an = new FreeVibrationAnalysis(m, MassMatrixType.VARIATIONAL_MASS_LUMPING, 0.0,
				0.0); // no damping

//		((FreeVibrationAnalysis) an).setAnalysisTypeToNonAdaptiveNewmark(NewmarkType.NewmarkAlpha,
//				0.8, 0.0, 1e-3, 200);

		((FreeVibrationAnalysis) an).setAnalysisTypeToNonAdaptiveNewmarkCrisfieldFormulation(
				NewmarkType.NewmarkAlpha, 0.8, 0.0, 1e-3, 200);

		// ((FreeVibrationAnalysis) an).setAnalysisTypeToCDM(0, 1e-5, 2000);

		Strategy s = an.getStrategy();
		s.setEchoLevel(EchoLevelType.OUTPUT);
		return an;
	}

	@Override
	public Mesh createMesh() {
		String fn = projectDir + '/' + projectName + '/' + meshFileName;
		MeshGenerator mg = new GidMeshGenerator(fn);
		return mg.getMesh(3);
	}

	@Override
	public Model createConditions(Model m) {
		Mesh mesh = m.getMesh();
		/*
		 * boundary conditions
		 */
		Constraint c1 = new Constraint(false, false, false);
		ArrayList<Node> side = MeshUtilities.seekNodesOnSurface(mesh, 0.0, 1.0, 0.0, 0.0);
		mesh.setConstraint(c1, side);

		/*
		 * load: activate at time 0.0 only; used for computing the static
		 * solution
		 */
		double F = -0.1 * 10e6;
		Node n1 = MeshUtilities.seekNode(mesh, 0.0, 12.0, 0.0);
		Node n2 = MeshUtilities.seekNode(mesh, 1.0, 12.0, 0.0);
		Force f1 = new Force(n1, 0.0, 0.0, F);
		Force f2 = new Force(n2, 0.0, 0.0, F);
		PulseFunctionRToR lambda = new PulseFunctionRToR(0.0, 1e-6, 1.0);
		f1.setTimeFactor(lambda);
		f2.setTimeFactor(lambda);
		m.addLoad(f1);
		m.addLoad(f2);

		/*
		 * gravity: activate all the time
		 */
		// double rho = 7850;
		// // double g = -9.81;
		// // FunctionRnToR f = new ConstantFunctionRnToR(rho * g);
		// for (int i = 0; i < m.getMesh().countBlocks(); i++) {
		// // Load l = new DistributedLoad(mesh.getBlock(i), null, f, null);
		// Load l = new GravityLoad(mesh.getBlock(i), rho);
		// m.addLoad(l);
		// }

		return m;
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 25850 * 10e6;
		double nu = 0.18;
		double rho = 7850;
		double t = 1.0;
		State ss = State.THREE_DIMENSIONAL;
		return new StVenantKirchhoffMM(E, nu, t, rho, ss);
	}

	@Override
	public Element createElement(MeshPart mp, MaterialModel mm) {
		return new StructuralElement(mp, mm);
	}

	public static void main(String[] args) {
		AbstractStructuralDynamicsDemo demo = new Beam3dFreeVibration();

		demo.run();
	}
}
